using System;
using System.Collections.Generic;
using UnityEngine;

public class EventCommander : MonoBehaviour
{
	public class GameEvent
	{
		public bool isWeak;

		public GameEventDelegate _event;

		public UnityEngine.Object receiver;

		public void Rize(UnityEngine.Object sender, params object[] args)
		{
			_event(sender, args);
		}
	}

	public delegate void GameEventDelegate(UnityEngine.Object sender, params object[] args);

	private Dictionary<string, List<GameEvent>> existingEvents;

	public string[] Events
	{
		set
		{
			InitEvents(value);
		}
	}

	private int ChkSameEvents(List<GameEvent> list, GameEventDelegate newEvent, UnityEngine.Object receiver)
	{
		for (int i = 0; i < list.Count; i++)
		{
			if (list[i]._event == newEvent && list[i].receiver == receiver)
			{
				return i;
			}
		}
		return -1;
	}

	private int ChkSameEvents(List<GameEvent> list, GameEvent newEvent)
	{
		return ChkSameEvents(list, newEvent._event, newEvent.receiver);
	}

	public void AddEventListener(UnityEngine.Object receiver, string eventName, GameEventDelegate callback)
	{
		AddEventListener(receiver, eventName, callback, false);
	}

	public void AddEventListener(UnityEngine.Object receiver, string eventName, GameEventDelegate callback, bool isWeak)
	{
		if (existingEvents == null)
		{
			BCWDebug.Log("cant add event " + eventName + " " + receiver.name + "! First call Init() function", "EventDispatcher", LogType.Error);
			return;
		}
		GameEvent gameEvent = new GameEvent();
		gameEvent.isWeak = isWeak;
		gameEvent._event = callback;
		gameEvent.receiver = receiver;
		if (existingEvents.ContainsKey(eventName))
		{
			int num = ChkSameEvents(existingEvents[eventName], gameEvent);
			if (num == -1)
			{
				existingEvents[eventName].Add(gameEvent);
			}
			else
			{
				existingEvents[eventName][num] = gameEvent;
			}
		}
		else
		{
			BCWDebug.Log("event which name '" + eventName + "' does not exist on this object", "EventDispatcher", LogType.Error);
		}
	}

	public bool RemoveEventListener(UnityEngine.Object receiver, GameEventDelegate callback)
	{
		bool result = false;
		foreach (KeyValuePair<string, List<GameEvent>> existingEvent in existingEvents)
		{
			result = RemoveEventListener(receiver, existingEvent.Key, callback);
		}
		return result;
	}

	public void RiseEvent(UnityEngine.Object sender, string eventName, params object[] args)
	{
		if (existingEvents == null || !existingEvents.ContainsKey(eventName))
		{
			BCWDebug.Log("cant rize event " + eventName + " ! First call Init() function", "EventDispatcher", LogType.Error);
			return;
		}
		GameEvent gameEvent = null;
		for (int i = 0; i < existingEvents[eventName].Count; i++)
		{
			gameEvent = existingEvents[eventName][i];
			if (gameEvent.receiver == null)
			{
				existingEvents[eventName].Remove(gameEvent);
				i--;
				continue;
			}
			try
			{
				gameEvent.Rize(sender, args);
				if (gameEvent.isWeak)
				{
					RemoveEventListener(gameEvent.receiver, gameEvent._event);
				}
			}
			catch (Exception ex)
			{
				RemoveEventListener(gameEvent.receiver, eventName);
				BCWDebug.Log("cant rize event " + eventName + " for " + gameEvent.receiver.name + " delegate removed /n" + ex.ToString(), "EventDispatcher", LogType.Error);
			}
		}
	}

	public bool RemoveEventListener(UnityEngine.Object receiver, string eventName)
	{
		for (int i = 0; i < existingEvents[eventName].Count; i++)
		{
			if (existingEvents[eventName][i].receiver == receiver)
			{
				existingEvents[eventName].RemoveAt(i);
				return true;
			}
		}
		return false;
	}

	public bool RemoveEventListener(UnityEngine.Object receiver, string eventName, GameEventDelegate callback)
	{
		int num = ChkSameEvents(existingEvents[eventName], callback, receiver);
		if (num != -1)
		{
			existingEvents[eventName].RemoveAt(num);
			return true;
		}
		return false;
	}

	public void RemoveAllEventsListeners()
	{
		if (existingEvents == null)
		{
			return;
		}
		foreach (KeyValuePair<string, List<GameEvent>> existingEvent in existingEvents)
		{
			existingEvent.Value.Clear();
		}
	}

	public void RemoveAllEventListeners(UnityEngine.Object receiver)
	{
		if (existingEvents == null)
		{
			return;
		}
		foreach (KeyValuePair<string, List<GameEvent>> existingEvent in existingEvents)
		{
			for (int i = 0; i < existingEvent.Value.Count; i++)
			{
				if (existingEvent.Value[i].receiver == receiver)
				{
					existingEvents[existingEvent.Key].RemoveAt(i);
					i--;
				}
			}
		}
	}

	public void RemoveAllEventListeners(string eventName)
	{
		existingEvents[eventName].Clear();
	}

	public void InitEvents(string[] eventNames)
	{
		if (existingEvents == null)
		{
			BCWDebug.Log("cant rize event! First call Init() function", "EventDispatcher", LogType.Error);
			return;
		}
		for (int i = 0; i < eventNames.Length; i++)
		{
			if (!existingEvents.ContainsKey(eventNames[i]))
			{
				existingEvents.Add(eventNames[i], new List<GameEvent>());
			}
		}
	}

	public virtual void Init()
	{
		if (existingEvents == null)
		{
			existingEvents = new Dictionary<string, List<GameEvent>>();
			InitEvents(new string[2] { "OnStart", "OnAwake" });
		}
	}

	public virtual void Awake()
	{
		Init();
		RiseEvent(this, "OnAwake");
	}

	public virtual void Start()
	{
		RiseEvent(this, "OnStart");
	}

	public virtual void OnEnable()
	{
	}

	public virtual void OnDisable()
	{
	}
}
